package com.ruoyi.business.service.impl;

import java.io.*;
import java.lang.reflect.Field;
import java.nio.channels.FileChannel;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.io.Files;
import com.ruoyi.business.api.ResearchPlanApi;
import com.ruoyi.business.constants.Constant;
import com.ruoyi.business.domain.*;
import com.ruoyi.business.enums.TaskAuditStatus;
import com.ruoyi.business.enums.UserSurveyStatus;
import com.ruoyi.business.model.*;
import com.ruoyi.business.request.*;
import com.ruoyi.business.response.*;
import com.ruoyi.business.service.*;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.core.domain.PageResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.RestTemplateUtil;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.config.ServerConfig;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import com.ruoyi.business.mapper.TaskMapper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

import static com.ruoyi.business.constants.JetCacheConstant.PLAN_LAYER_CACHE_NAME;
import static com.ruoyi.business.constants.JetCacheConstant.USER_TASK_POINT_CACHE_NAME;

/**
 * 任务Service业务层处理
 *
 * @author Eric
 * @date 2024-03-17
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements ITaskService {

    private final ITaskUserService taskUserService;
    private final ITaskPointService taskPointService;
    private final ITaskSurveyService taskSurveyService;
    private final ITaskAnnexService taskAnnexService;
    private final ISysUserService userService;
    private final IResearchPlanService researchPlanService;
    private final ServerConfig serverConfig;
    private final ISysDictDataService dictDataService;
    private final RestTemplate restTemplate;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean createTask(TaskCreateReq req) {
        Long[] userIds = req.getUserIds();
        if (ArrayUtil.isEmpty(userIds)) {
            throw new ServiceException("任务用户不能为空");
        }

        String currentUserName = SecurityUtils.getUsername();
        Task task = new Task();
        task.setTaskName(req.getTaskName());
        task.setSurveyWaterBodyName(req.getSurveyWaterBodyName());
        task.setBusinessType(req.getBusinessType());
        task.setTaskRemark(req.getTaskRemark());
        task.setSource(req.getSource());
        task.setCreateBy(currentUserName);
        task.setCreateTime(new Date());
        task.setAuditStatus(TaskAuditStatus.DRAFT.getKey());
        task.setResearchPlanId(req.getResearchPlanId());
        this.save(task);
        Long taskId = task.getId();

        List<TaskUser> taskUsers = Lists.newArrayListWithCapacity(userIds.length);
        for (Long userId : userIds) {
            TaskUser taskUser = new TaskUser(userId, taskId);
            taskUser.setCreateBy(currentUserName);
            taskUser.setCreateTime(new Date());
            taskUser.setSurveyStatus(UserSurveyStatus.IN_PROGRESS.getKey());
            taskUsers.add(taskUser);
        }
        taskUserService.saveBatch(taskUsers);
        List<TaskPointReq> pointList = req.getPointList();
        List<TaskPoint> taskPoints = Lists.newArrayListWithCapacity(pointList.size());
        for (TaskPointReq taskPointReq : pointList) {
            TaskPoint taskPoint = new TaskPoint();
            taskPoint.setPointName(taskPointReq.getPointName());
            taskPoint.setLatitude(taskPointReq.getLatitude());
            taskPoint.setLongitude(taskPointReq.getLongitude());
            taskPoint.setTaskId(taskId);
            taskPoint.setCreateBy(currentUserName);
            taskPoint.setCreateTime(new Date());
            taskPoints.add(taskPoint);
        }
        taskPointService.saveBatch(taskPoints);

        return true;
    }

    @Override
    public TaskRes getTaskById(Long id) {
        Task task = getById(id);
        if (task == null) {
            throw new ServiceException("任务获取失败。");
        }
        TaskRes res = new TaskRes();
        res.setId(task.getId());
        res.setTaskName(task.getTaskName());
        res.setSurveyWaterBodyName(task.getSurveyWaterBodyName());
        res.setBusinessType(task.getBusinessType());
        res.setTaskRemark(task.getTaskRemark());
        res.setResearchPlanId(task.getResearchPlanId());
        Long[] userIds = taskUserService.getTaskUserIds(task.getId());
        res.setUserIds(userIds);
        List<TaskPointReq> pointList = taskPointService.getTaskPointList(task.getId());
        res.setPointList(pointList);
        return res;
    }

    @Override
    public Boolean submitAuditTask(Long taskId) {
        Task task = getById(taskId);
        if (task == null) {
            throw new ServiceException("任务获取失败。");
        }
        if (!ObjectUtil.equals(task.getAuditStatus(), TaskAuditStatus.DRAFT.getKey())) {
            throw new ServiceException("任务审核状态异常。");
        }
        Task updateTask = new Task();
        updateTask.setId(taskId);
        updateTask.setAuditStatus(TaskAuditStatus.AUDIT.getKey());
        return this.updateById(updateTask);
    }

    @Override
    public Boolean auditTask(TaskAuditReq req) {
        Task task = getById(req.getId());
        if (task == null) {
            log.error("【任务审核异常】任务未找到，参数：[{}]", req);
            throw new ServiceException("任务获取失败。");
        }
        if (ObjectUtil.equals(task.getAuditStatus(), TaskAuditStatus.DRAFT.getKey())) {
            log.error("【任务审核异常】任务为草稿状态，参数：[{}]", req);
            throw new ServiceException("任务未提交，请先提交后再审核。");
        }
        if (!ObjectUtil.equals(req.getAuditStatus(), TaskAuditStatus.APPROVED.getKey()) &&
                !ObjectUtil.equals(req.getAuditStatus(), TaskAuditStatus.REVIEW_REJECTION.getKey())) {
            log.error("【任务审核异常】审核状态异常，参数：[{}]", req);
            throw new ServiceException("审核状态异常。");
        }
        if (ObjectUtil.equals(task.getAuditStatus(), TaskAuditStatus.APPROVED.getKey()) ||
                ObjectUtil.equals(task.getAuditStatus(), TaskAuditStatus.REVIEW_REJECTION.getKey())) {
            return true;
        }
        Task updateTask = new Task();
        updateTask.setId(req.getId());
        updateTask.setAuditStatus(req.getAuditStatus());
        updateTask.setAuditTime(new Date());
        if (ObjectUtil.equals(req.getAuditStatus(), TaskAuditStatus.REVIEW_REJECTION.getKey())) {
            updateTask.setReasonRejection(req.getReasonRejection());
        }
        return this.updateById(updateTask);
    }

    @Override
    public Boolean end(Long taskId) {
        Task task = getById(taskId);
        if (task == null) {
            log.error("【任务结束异常】任务未找到，参数：[{}]", taskId);
            throw new ServiceException("任务获取失败。");
        }
        if (!ObjectUtil.equals(task.getAuditStatus(), TaskAuditStatus.APPROVED.getKey())) {
            log.error("【任务结束异常】任务未提交审核，或审核未通过，参数：[{}]", taskId);
            throw new ServiceException("任务未提交审核，或审核未通过。");
        }
        Task updateTask = new Task();
        updateTask.setId(taskId);
        return this.updateById(updateTask);
    }

    @Override
    public PageResult<ApiTaskRes> pageTaskList(ApiTaskReq req) {
        req.setUserId(SecurityUtils.getUserId());
        PageUtils.startPage();
        List<ApiTaskRes> list = baseMapper.pageTaskList(req);
        if (CollUtil.isNotEmpty(list)) {
            for (ApiTaskRes apiTaskRes : list) {
                List<TaskPoint> taskPoints = taskPointService.list(Wrappers.lambdaQuery(TaskPoint.class).eq(TaskPoint::getTaskId, apiTaskRes.getId()));
                if (CollUtil.isNotEmpty(taskPoints) && taskPoints.size() == 1) {
                    TaskPoint taskPoint = taskPoints.get(0);
                    apiTaskRes.setTaskPointId(taskPoint.getId());
                }
//                apiTaskRes.setBusinessType(DictUtils.getDictLabel(Constant.TASK_BUSINESS_TYPE_DICT_KEY, apiTaskRes.getBusinessType()));
//                apiTaskRes.setSurveyWaterBodyName(DictUtils.getDictLabel(Constant.SURVEY_WATER_BODY_NAME_DICT_KEY, apiTaskRes.getSurveyWaterBodyName()));
            }
        }
        return PageResult.empty(list);
    }

    @Override
    public List<ApiTaskPointRes> getTaskPointApi(Long taskId) {
        Task task = getById(taskId);
        if (task == null) {
            throw new ServiceException("任务获取失败。");
        }
        Long userId = SecurityUtils.getUserId();
        List<TaskPoint> pointList = taskPointService.list(Wrappers.lambdaQuery(TaskPoint.class)
                .eq(TaskPoint::getTaskId, taskId));
        List<ApiTaskPointRes> resLit = Lists.newArrayListWithCapacity(pointList.size());
        if (CollUtil.isNotEmpty(pointList)) {
            for (TaskPoint taskPoint : pointList) {
                TaskUser taskUser = taskUserService.getOne(Wrappers.lambdaQuery(TaskUser.class)
                        .eq(TaskUser::getTaskId, taskId)
                        .eq(TaskUser::getUserId, userId));
                ApiTaskPointRes res = new ApiTaskPointRes();
                res.setId(taskPoint.getId());
                res.setTaskId(taskId);
                res.setPointName(taskPoint.getPointName());
                res.setLongitude(taskPoint.getLongitude());
                res.setLatitude(taskPoint.getLatitude());
                if (taskUser != null) {
                    res.setSurveyStatus(taskUser.getSurveyStatus());
                } else {
                    res.setSurveyStatus(UserSurveyStatus.IN_PROGRESS.getKey());
                }
                resLit.add(res);
            }
        }
        return resLit;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean updateTask(TaskUpdateReq req) {
        String currentUserName = SecurityUtils.getUsername();
        Task task = new Task();
        task.setId(req.getId());
        task.setTaskName(req.getTaskName());
        task.setSurveyWaterBodyName(req.getSurveyWaterBodyName());
        task.setBusinessType(req.getBusinessType());
        task.setTaskRemark(req.getTaskRemark());
        task.setUpdateBy(currentUserName);
        task.setUpdateTime(new Date());
//        task.setAuditStatus(TaskAuditStatus.DRAFT.getKey());
        task.setResearchPlanId(req.getResearchPlanId());
        this.updateById(task);

        //---------任务用户处理------------------

        // 先查出旧用户
        List<TaskUser> oldTaskUserList = taskUserService.list(Wrappers.lambdaQuery(TaskUser.class)
                .eq(TaskUser::getTaskId, req.getId()));
        Long[] userIds = req.getUserIds();
        List<TaskUser> taskUserList = Lists.newArrayListWithCapacity(userIds.length);
        // 存储新用户
        List<Long> addTaskUserIdList = Lists.newArrayList();

        List<Long> oldTaskUserIdList = oldTaskUserList.stream().map(TaskUser::getUserId).collect(Collectors.toList());

        for (Long userId : userIds) {
            if (oldTaskUserIdList.contains(userId)) {
                oldTaskUserIdList.remove(userId);
            } else {
                addTaskUserIdList.add(userId);
            }
        }

        if (CollUtil.isNotEmpty(oldTaskUserIdList)) {
            for (Long taskUserId : oldTaskUserIdList) {
                TaskUser oldTaskUser = taskUserService.getOne(Wrappers.lambdaQuery(TaskUser.class)
                        .eq(TaskUser::getTaskId, req.getId())
                        .eq(TaskUser::getUserId, taskUserId));
                if (oldTaskUser == null) {
                    continue;
                }
                if (!ObjectUtil.equals(oldTaskUser.getSurveyStatus(), UserSurveyStatus.IN_PROGRESS.getKey())) {
                    throw new ServiceException("不能将已提交调研数据的用户删除。");
                }
                taskUserService.remove(Wrappers.lambdaQuery(TaskUser.class)
                        .eq(TaskUser::getTaskId, req.getId())
                        .eq(TaskUser::getUserId, taskUserId));
            }
        }

        for (Long userId : addTaskUserIdList) {
            TaskUser taskUser = new TaskUser(userId, req.getId());
            taskUser.setCreateBy(currentUserName);
            taskUser.setCreateTime(new Date());
            taskUserList.add(taskUser);
        }
        taskUserService.saveBatch(taskUserList);

        //---------任务点位处理------------------
        List<TaskPointReq> newPointList = req.getPointList();
        List<TaskPoint> oldPointList = taskPointService.list(Wrappers.lambdaQuery(TaskPoint.class)
                .eq(TaskPoint::getTaskId, req.getId()));
        List<Long> newPointIdList = Lists.newArrayListWithCapacity(newPointList.size());
        // 存储新点位
        List<TaskPoint> updateTaskPoints = Lists.newArrayListWithCapacity(newPointList.size());
        List<TaskPoint> addTaskPoints = Lists.newArrayListWithCapacity(newPointList.size());
        for (TaskPointReq taskPointReq : newPointList) {
            TaskPoint taskPoint = new TaskPoint();
            taskPoint.setPointName(taskPointReq.getPointName());
            taskPoint.setLatitude(taskPointReq.getLatitude());
            taskPoint.setLongitude(taskPointReq.getLongitude());
            taskPoint.setTaskId(req.getId());
            taskPoint.setCreateBy(currentUserName);
            taskPoint.setCreateTime(new Date());
            if (ObjectUtil.isNotNull(taskPointReq.getId())) {
                taskPoint.setId(taskPointReq.getId());
                newPointIdList.add(taskPointReq.getId());
                updateTaskPoints.add(taskPoint);
            } else {
                addTaskPoints.add(taskPoint);
            }
        }

        List<Long> oldPointIdList = oldPointList.stream().map(TaskPoint::getId).collect(Collectors.toList());

        // 取差集，剔除旧点位中没有包含的新点位，进行删除
        Collection<Long> deletePointIds = CollectionUtils.subtract(oldPointIdList, newPointIdList);
        if (CollUtil.isNotEmpty(deletePointIds)) {
            taskPointService.removeBatchByIds(deletePointIds);
        }

        if (CollUtil.isNotEmpty(updateTaskPoints)) {
            taskPointService.updateBatchById(updateTaskPoints);
        }
        if (CollUtil.isNotEmpty(addTaskPoints)) {
            taskPointService.saveBatch(addTaskPoints);
        }


        return true;
    }

    @Override
    public ApiTaskPointInfoRes getTaskPointInfo(Long taskId, Long pointId) {
        Task task = getById(taskId);
        if (task == null) {
            throw new ServiceException("任务获取失败。");
        }
        TaskPoint taskPoint = taskPointService.getById(pointId);
        if (taskPoint == null) {
            throw new ServiceException("任务点位获取失败。");
        }
        List<ApiTaskAnnexRes> annexList = taskAnnexService.listTaskAnnex(pointId);
        TaskSurvey taskSurvey = taskSurveyService.getByTaskIdAndPointId(taskId, pointId);
        String surveyRemark = "";
        Long taskSurveyId = null;
        if (taskSurvey != null) {
            taskSurveyId = taskSurvey.getId();
            surveyRemark = taskSurvey.getRemark();
        }
        String businessType = DictUtils.getDictLabel(Constant.TASK_BUSINESS_TYPE_DICT_KEY, task.getBusinessType());
        String surveyWaterBodyName = DictUtils.getDictLabel(Constant.SURVEY_WATER_BODY_NAME_DICT_KEY, task.getSurveyWaterBodyName());
        return ApiTaskPointInfoRes.builder()
                .id(task.getId())
                .taskName(task.getTaskName())
                .surveyWaterBodyName(surveyWaterBodyName)
                .businessType(businessType)
                .pointId(taskPoint.getId())
                .pointName(taskPoint.getPointName())
                .longitude(taskPoint.getLongitude())
                .latitude(taskPoint.getLatitude())
                .taskSurveyId(taskSurveyId)
                .annexList(annexList)
                .surveyRemark(surveyRemark)
                .build();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean submitSurveyTask(ApiTaskSubmitReq req) {
        Long taskId = req.getTaskId();
        Long userId = SecurityUtils.getUserId();

        TaskUser taskUser = taskUserService.getOne(Wrappers.lambdaQuery(TaskUser.class)
                .eq(TaskUser::getUserId, userId)
                .eq(TaskUser::getTaskId, taskId));
        if (taskUser == null) {
            throw new ServiceException("你没有调研该任务的权限。");
        }

        Task task = getById(taskId);
        if (task == null) {
            throw new ServiceException("任务获取失败。");
        }

        Long taskPointId = req.getTaskPointId();
        TaskSurvey oldTaskSurvey = taskSurveyService.getByTaskIdAndPointId(taskId, taskPointId);
        TaskSurvey taskSurvey = new TaskSurvey();
        if (oldTaskSurvey == null) {
            taskSurvey.setTaskId(taskId);
            taskSurvey.setUserId(userId);
            taskSurvey.setTaskPointId(taskPointId);
            taskSurvey.setRemark(req.getRemark());
            taskSurvey.setCreateBy(SecurityUtils.getUsername());
            taskSurvey.setCreateTime(new Date());
            taskSurveyService.save(taskSurvey);
        } else {
            taskSurvey.setId(oldTaskSurvey.getId());
            taskSurvey.setTaskId(taskId);
            taskSurvey.setUserId(userId);
            taskSurvey.setTaskPointId(taskPointId);
            taskSurvey.setRemark(req.getRemark());
            taskSurvey.setUpdateBy(SecurityUtils.getUsername());
            taskSurvey.setUpdateTime(new Date());
            taskSurveyService.updateById(taskSurvey);
        }
        TaskUser updateTaskUser = new TaskUser();
        updateTaskUser.setId(taskUser.getId());
        updateTaskUser.setSurveyStatus(UserSurveyStatus.SUBMITTED.getKey());
        taskUserService.updateById(updateTaskUser);

        Task updateTask = new Task();
        updateTask.setId(taskId);
        updateTask.setAuditStatus(TaskAuditStatus.AUDIT.getKey());
        return this.updateById(updateTask);
    }

    @Override
    public List<ApiTaskPointRes> getTaskPointByPlanId(Long planId) {
        return baseMapper.getTaskPointByPlanId(planId, SecurityUtils.getUserId());
    }

    @Override
    public List<Map<String, Object>> getPointByTask(Long taskId) {
        List<TaskPoint> pointList = taskPointService.list(Wrappers.lambdaQuery(TaskPoint.class)
                .eq(TaskPoint::getTaskId, taskId));
        List<Map<String, Object>> list = Lists.newArrayList();
        if (CollUtil.isNotEmpty(pointList)) {
            int index = 0;
            for (TaskPoint taskPoint : pointList) {
                Map<String, Object> map = Maps.newHashMap();
                map.put("index", index);
                index++;
                map.put("id", taskPoint.getId());
                map.put("name", taskPoint.getPointName());
                list.add(map);
            }
        }
        return list;
    }

    @Override
    public List<TaskSurveyRes> getSurveyByPointId(Long pointId, Long userId) {
        LambdaQueryWrapper<TaskSurvey> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(TaskSurvey::getTaskPointId, pointId);
        if (ObjectUtil.isNotNull(userId)) {
            lambdaQueryWrapper.eq(TaskSurvey::getUserId, userId);
        }
        lambdaQueryWrapper.orderByDesc(BaseEntity::getCreateTime);
        List<TaskSurvey> list = taskSurveyService.list(lambdaQueryWrapper);
        List<TaskSurveyRes> resList = Lists.newArrayListWithCapacity(list.size());
        if (CollUtil.isNotEmpty(list)) {
            list.forEach(survey -> {
                TaskSurveyRes res = new TaskSurveyRes();
                BeanUtil.copyProperties(survey, res);
                LambdaQueryWrapper<TaskAnnex> annexLambdaQueryWrapper = Wrappers.lambdaQuery(TaskAnnex.class);
                annexLambdaQueryWrapper.eq(TaskAnnex::getTaskPointId, pointId);
                annexLambdaQueryWrapper.eq(TaskAnnex::getUserId, survey.getUserId());
                annexLambdaQueryWrapper.orderByDesc(BaseEntity::getCreateTime);
                List<TaskAnnex> annexes = taskAnnexService.list(annexLambdaQueryWrapper);
                if (CollUtil.isNotEmpty(annexes)) {
                    for (TaskAnnex annex : annexes) {
                        annex.setFileUrl(serverConfig.getUrl() + annex.getFileUrl());
                    }
                }
                res.setList(annexes);

                SysUser user = userService.getById(survey.getUserId());
                res.setUserName(user.getUserName());

                resList.add(res);
            });
        }
        return resList;
    }

    @Override
    public List<TaskExportRes> getExportList(TaskExportReq req, String exportPath) {
        List<TaskExportModel> taskList = baseMapper.getExportList(req);
        if (CollUtil.isNotEmpty(taskList)) {
            List<TaskExportRes> resList = Lists.newArrayList();
            for (TaskExportModel taskModel : taskList) {
                ResearchPlan researchPlan = researchPlanService.getById(taskModel.getResearchPlanId());
                if (researchPlan == null) {
                    continue;
                }
                String businessType = DictUtils.getDictLabel(Constant.TASK_BUSINESS_TYPE_DICT_KEY, taskModel.getBusinessType());
                String surveyWaterBodyName = DictUtils.getDictLabel(Constant.SURVEY_WATER_BODY_NAME_DICT_KEY, taskModel.getSurveyWaterBodyName());
                String sourceStr = convertSource(taskModel.getSource());
                // 获取任务用户
                List<TaskUserExportRes> taskUserExportResList = taskUserService.getExportList(taskModel.getTaskId());
                if (CollUtil.isNotEmpty(taskUserExportResList)) {
                    for (TaskUserExportRes taskUserExportRes : taskUserExportResList) {
                        // 获取任务上报情况
                        LambdaQueryWrapper<TaskSurvey> lambdaQueryWrapper = Wrappers.lambdaQuery();
                        lambdaQueryWrapper.eq(TaskSurvey::getTaskId, taskModel.getTaskId());
                        lambdaQueryWrapper.eq(TaskSurvey::getTaskPointId, taskModel.getPointId());
                        lambdaQueryWrapper.eq(TaskSurvey::getUserId, taskUserExportRes.getUserId());
                        lambdaQueryWrapper.last("limit 1");
                        TaskSurvey taskSurvey = taskSurveyService.getOne(lambdaQueryWrapper);
                        TaskExportRes res = new TaskExportRes();
                        BeanUtil.copyProperties(taskModel, res);
                        res.setResearchPlanName(researchPlan.getPlanName());
                        res.setUserName(taskUserExportRes.getUserName());
                        res.setPhoneNumber(taskUserExportRes.getPhonenumber());
                        res.setBusinessType(businessType);
                        res.setSurveyWaterBodyName(surveyWaterBodyName);
                        res.setSource(sourceStr);
                        if (taskSurvey != null) {
                            res.setSurveyRemark(taskSurvey.getRemark());
                            res.setSurveyTime(taskSurvey.getCreateTime());
                        }
                        // 获取任务附件
                        LambdaQueryWrapper<TaskAnnex> annexLambdaQueryWrapper = Wrappers.lambdaQuery();
                        annexLambdaQueryWrapper.eq(TaskAnnex::getTaskId, taskModel.getTaskId());
                        annexLambdaQueryWrapper.eq(TaskAnnex::getTaskPointId, taskModel.getPointId());
                        annexLambdaQueryWrapper.eq(TaskAnnex::getUserId, taskUserExportRes.getUserId());
                        List<TaskAnnex> taskAnnexList = taskAnnexService.list(annexLambdaQueryWrapper);
                        if (CollUtil.isNotEmpty(taskAnnexList)) {
                            String fileName = StrUtil.format("{}({})", taskUserExportRes.getUserName(), taskUserExportRes.getUserId());
                            // 根据用户名称和id创建文件夹打包zip
                            String filePath = StrUtil.format("{}/{}", exportPath, fileName);
                            FileUtil.mkParentDirs(filePath);
                            for (TaskAnnex taskAnnex : taskAnnexList) {
                                String localFilePath = getLocalFilePath(taskAnnex.getFileUrl());
                                File srcFile = new File(localFilePath);
                                // 文件全名(如：demo.txt)
                                String simplePath = Files.simplifyPath(srcFile.getName());
                                // 组装目标文件路径
                                String destFilePath = filePath + File.separator + simplePath;

                                File destFile = new File(destFilePath);
                                if (FileUtil.isNotEmpty(srcFile)) {
                                    try {
                                        Files.createParentDirs(destFile);
                                        Files.copy(srcFile, destFile);
                                    } catch (IOException e) {
                                        e.printStackTrace();
                                        throw new ServiceException("文件复制失败");
                                    }
                                    res.setFilePathName(fileName);
                                }
                            }
                        }
                        resList.add(res);
                    }
                } else {
                    TaskExportRes res = new TaskExportRes();
                    BeanUtil.copyProperties(taskModel, res);
                    res.setResearchPlanName(researchPlan.getPlanName());
                    res.setBusinessType(businessType);
                    res.setSurveyWaterBodyName(surveyWaterBodyName);
                    res.setSource(sourceStr);
                    resList.add(res);
                }
            }
            return resList;
        }
        return Collections.emptyList();
    }

    @Override
    public List<ApiTaskPointRes> getTaskUserPointApi(Long researchPlanId, Long userId) {
        return baseMapper.getTaskUserPointApi(researchPlanId, userId);
    }

    @Override
    public List<JSONObject> selectTaskUser(Long planId, String name) {
        List<Map<String, Object>> list = baseMapper.selectTaskUser(planId);
        if (CollUtil.isNotEmpty(list)) {
            List<JSONObject> resultList = Lists.newArrayListWithCapacity(list.size());
            for (Map<String, Object> map : list) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.set("id", MapUtil.getLong(map, "userId"));
                jsonObject.set("name", MapUtil.getStr(map, "userName"));
                resultList.add(jsonObject);
            }
            return resultList;
        }
        return Collections.emptyList();
    }

    private String getLocalFilePath(String filePath) {
        if (StrUtil.isEmpty(filePath)) {
            return "";
        }
        String path = StrUtil.sub(filePath,
                filePath.indexOf(Constants.RESOURCE_PREFIX) + Constants.RESOURCE_PREFIX.length() + "/upload".length(), filePath.length());
        return RuoYiConfig.getUploadPath() + path;
    }

    private String convertSource(String source) {
        String sourceStr = "";
        if (StrUtil.equals(source, "0")) {
            sourceStr = "APP";
        } else if (StrUtil.equals(source, "1")) {
            sourceStr = "后台";
        }
        return sourceStr;
    }

    public void syncData(Long[] ids){
        if(ids == null || ids.length == 0){
            return;
        }
        LambdaQueryWrapper<Task> query = Wrappers.lambdaQuery(Task.class)
                .in(Task::getId, ids)
                .eq(Task::getSyncStatus, 2);
        List<Task> taskList = list(query);


        for(Task task : taskList){
            Task ntask = getById(task.getId());
            if(ntask.getSyncStatus() != 2){
               continue;
            }
            try{
                WaterEnvTaskVO taskVo = new WaterEnvTaskVO();
                BeanUtil.copyProperties(task, taskVo);
                String surveyWaterBodyName = dictDataService.selectDictLabel("survey_water_body_name", task.getSurveyWaterBodyName());
                taskVo.setSurveyWaterBodyName(surveyWaterBodyName);

                //附件
                LambdaQueryWrapper<TaskAnnex> annexLambdaQueryWrapper = Wrappers.lambdaQuery(TaskAnnex.class)
                    .eq(TaskAnnex::getTaskId, task.getId());
                List<TaskAnnex> annexes = taskAnnexService.list(annexLambdaQueryWrapper);
                List<TaskAnnexVO> taskAnnexVOList = Lists.newArrayList();
                taskVo.setTaskAnnexList(taskAnnexVOList);

                for(TaskAnnex annex : annexes){
                    TaskAnnexVO taskAnnexVO = new TaskAnnexVO();
                    BeanUtil.copyProperties(annex, taskAnnexVO);
                    SysUser user = userService.getById(annex.getUserId());
                    taskAnnexVO.setUserName(user.getUserName());
                    taskAnnexVOList.add(taskAnnexVO);

                }

                //用户
                LambdaQueryWrapper<TaskUser> userQuery = Wrappers.lambdaQuery(TaskUser.class)
                        .eq(TaskUser::getTaskId, task.getId());
                List<TaskUser> userList = taskUserService.list(userQuery);
                List<TaskUserVO> userVOS = Lists.newArrayList();
                taskVo.setUserList(userVOS);
                for(TaskUser user : userList){
                    TaskUserVO taskUserVO = new TaskUserVO();
                    BeanUtil.copyProperties(user, taskUserVO);
                    SysUser userx = userService.getById(user.getUserId());
                    taskUserVO.setUserName(userx.getUserName());
                    userVOS.add(taskUserVO);
                }

                //点位
                LambdaQueryWrapper<TaskPoint> pointQuery = Wrappers.lambdaQuery(TaskPoint.class)
                        .eq(TaskPoint::getTaskId, task.getId());
                List<TaskPoint> pointList = taskPointService.list(pointQuery);
                List<TaskPointVO> taskPointVOS = Lists.newArrayList();
                taskVo.setTaskPointSList(taskPointVOS);
                for(TaskPoint point : pointList){
                    TaskPointVO pointVO = new TaskPointVO();
                    BeanUtil.copyProperties(point, pointVO);
                    taskPointVOS.add(pointVO);
                }

                //调研
                LambdaQueryWrapper<TaskSurvey> surveyQuery = Wrappers.lambdaQuery(TaskSurvey.class)
                        .eq(TaskSurvey::getTaskId, task.getId());
                List<TaskSurvey> taskSurveys = taskSurveyService.list(surveyQuery);
                List<TaskSurveyVO> taskSurveyVOS = Lists.newArrayList();
                taskVo.setTaskSurveyList(taskSurveyVOS);
                for(TaskSurvey survey : taskSurveys){
                    TaskSurveyVO surveyVO = new TaskSurveyVO();
                    BeanUtil.copyProperties(survey, surveyVO);
                    SysUser userx = userService.getById(survey.getUserId());
                    surveyVO.setUserName(userx.getUserName());
                    taskSurveyVOS.add(surveyVO);
                }
                File outputFile = null;
                if(annexes.size() > 0){
                    String tempFileDir = RuoYiConfig.getProfile() + File.separator+"tempzip"+File.separator;
                    File dir = new File(tempFileDir);
                    if(!dir.exists()){
                        dir.mkdirs();
                    }
                    String uuid = UUID.randomUUID().toString();
                    String zipFile = tempFileDir + uuid + ".zip";
                    outputFile = new File(zipFile);
                    InputStream input = null;
                    ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(outputFile));

                    List<String> fileNames = Lists.newArrayList();
                    for(TaskAnnex annex : annexes) {
                        String zipEntryName = StringUtils.substringAfter(annex.getFileUrl(), Constants.RESOURCE_PREFIX);
                        String filePath = RuoYiConfig.getProfile() + zipEntryName;
                        File file = new File(filePath);
                        if(fileNames.contains(file.getAbsolutePath())){
                            continue;
                        }else{
                            fileNames.add(file.getAbsolutePath());
                        }

                        input = new FileInputStream(file);
                        zipOut.putNextEntry(new ZipEntry(zipEntryName));
                        int temp = 0;
                        while ((temp = input.read()) != -1) {
                            zipOut.write(temp);
                        }
                        input.close();
                    }
                    zipOut.close();

                }

                MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
                if(outputFile != null) {
                    params.add("file", new FileSystemResource(outputFile));
                }
                ObjectMapper objectMapper = new ObjectMapper();
                String userJson= objectMapper.writeValueAsString(taskVo);

                params.add("taskInfo", userJson);
                params.add("token", RuoYiConfig.getYaoganToken());

                //设置Header参数
                HttpHeaders headers = new HttpHeaders();
                headers.add("Accept","application/json");
                headers.add("Content-Type","multipart/form-data;charset=UTF-8");
//                if(outputFile != null){
//                    // 添加表单字段
//                    params.add("file", outputFile);
//                }
//                RestTemplate restTemplate = SpringUtils.getBean("httpClientTemplate");
                HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(params, headers);
                JSONObject result = restTemplate.postForObject(RuoYiConfig.getYaoganUrl(), formEntity, JSONObject.class);
                int code = result.getInt("code");
                if(code == 200){
                    log.info("文件上传成功");
                    LambdaUpdateWrapper<Task> updateWrapper1 = Wrappers.lambdaUpdate(Task.class)
                            .eq(Task::getId, task.getId())
                            .set(Task::getSyncStatus, 1);
                    update(updateWrapper1);
                }else{
                    String message = result.getStr("msg", "");
                    log.error("文件上传失败:"+message);
                    LambdaUpdateWrapper<Task> updateWrapper1 = Wrappers.lambdaUpdate(Task.class)
                            .eq(Task::getId, task.getId())
                            .set(Task::getSyncStatus, 0);
                    update(updateWrapper1);
                }

            }catch (Exception ex){
                log.error("文件上传失败:"+ex.getMessage());
                LambdaUpdateWrapper<Task> updateWrapper1 = Wrappers.lambdaUpdate(Task.class)
                        .eq(Task::getId, task.getId())
                        .set(Task::getSyncStatus, 0);
                update(updateWrapper1);
            }
        }
    }

}
